package com.iltgcl.echovoicedemo.ui.settings

import android.os.Bundle
import android.text.Editable
import android.text.InputType
import android.text.TextWatcher
import android.widget.EditText
import androidx.fragment.app.viewModels
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import com.iltgcl.echovoice.client.EchoVoiceUtils
import com.iltgcl.echovoice.di.ApplicationScope
import com.iltgcl.echovoicedemo.R
import com.iltgcl.echovoicedemo.data.SettingsRepository
import com.iltgcl.echovoicedemo.ui.base.BasePreferenceFragment
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
class SettingsFragment : BasePreferenceFragment() {
    private val viewModel:SettingsViewModel by viewModels()

    @Inject
    lateinit var settingsRepository: SettingsRepository

    @Inject
    @ApplicationScope
    lateinit var applicationScope: CoroutineScope

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences, rootKey)

        findPreference<EditTextPreference>(getString(R.string.pref_speech_speed_key))?.apply {
            setOnBindEditTextListener {
                it.inputType = InputType.TYPE_CLASS_NUMBER
                it.addTextChangedListener(NumberTextWatcher(it, MIN_SPEECH_SPEED, MAX_SPEECH_SPEED, SPEECH_DEFAULT))
                applicationScope.launch {
                    delay(200L)
                    it.selectAll()
                }
            }
        }
        findPreference<EditTextPreference>(getString(R.string.pref_speech_volume_key))?.apply {
            setOnBindEditTextListener {
                it.inputType = InputType.TYPE_CLASS_NUMBER
                it.addTextChangedListener(NumberTextWatcher(it, MIN_SPEECH_VOLUME, MAX_SPEECH_VOLUME, SPEECH_DEFAULT))
                applicationScope.launch {
                    delay(200L)
                    it.selectAll()
                }
            }
        }
        findPreference<EditTextPreference>(getString(R.string.pref_speech_pitch_key))?.apply {
            setOnBindEditTextListener {
                it.inputType = InputType.TYPE_CLASS_NUMBER
                it.addTextChangedListener(NumberTextWatcher(it, MIN_SPEECH_PITCH, MAX_SPEECH_PITCH, SPEECH_DEFAULT))
                applicationScope.launch {
                    delay(200L)
                    it.selectAll()
                }
            }
        }

        //初始化发音人列表
        findPreference<ListPreference>(getString(R.string.pref_voice_name_key))?.apply {
            entries = EchoVoiceUtils.getVoiceNameEntries(context)
            val intVals:IntArray = EchoVoiceUtils.getVoiceNameValues(context)?: IntArray(0)
            entryValues = intVals.map { it.toString() }.toTypedArray()
            val curVal = intVals.firstOrNull { it == settingsRepository.getVoiceName()}
            if (curVal == null) {
                value = intVals[0].toString()
            } else {
                value = curVal.toString()
            }
        }
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        setupSnackbar(viewModel.snackbarText)
    }

    private inner class NumberTextWatcher(
        val editText: EditText,
        val min:Int,
        val max:Int,
        val def:Int): TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            when {
                s == null -> {}
                s.isEmpty() || s.isBlank() -> {
                    s.clear()
                    s.append(def.toString())
                    editText.text = s
                    editText.selectAll()
                }
                else -> {
                    val number = Integer.parseInt(s.toString())
                    when {
                        number > max -> {
                            s.clear()
                            s.append(max.toString())
                            editText.text = s
                            editText.selectAll()
                        }

                        number < min -> {
                            s.clear()
                            s.append(min.toString())
                            editText.text = s
                            editText.selectAll()
                        }
                        else -> { }
                    }
                }
            }
        }
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
    }

    companion object {
        private const val SPEECH_DEFAULT = 50
        private const val MIN_SPEECH_SPEED = 0
        private const val MAX_SPEECH_SPEED = 600
        private const val MIN_SPEECH_VOLUME = 0;
        private const val MAX_SPEECH_VOLUME = 100;
        private const val MIN_SPEECH_PITCH = 0;
        private const val MAX_SPEECH_PITCH = 100;
    }
}